package com.jiinfo.auth;

import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;

import com.jfinal.plugin.activerecord.Record;
import com.jiinfo.config.ConstConfig;
import com.jiinfo.model.Resource;
import com.jiinfo.model.Role;
import com.jiinfo.model.User;

public class UserRealm extends AuthorizingRealm{

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		String userId=(String)arg0.fromRealm(getName()).iterator().next();
		if(userId!=null){
			SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
			List<Record> records=Role.dao.getRolesByUserId(userId);
			for (Record record : records) {
				simpleAuthorizationInfo.addRole(record.getStr("code"));
				addResourceOfRole(record,simpleAuthorizationInfo);
			}
			return simpleAuthorizationInfo;
		}
		
		return null;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken arg0) throws AuthenticationException {
		
		UsernamePasswordToken userToken = (UsernamePasswordToken)arg0;
		
		Record record=User.dao.getUserByUsername(userToken.getUsername());
		
		if(record==null){
			//账号不存在
			throw new UnknownAccountException();
		}
		
		String loginPassword=String.valueOf(userToken.getPassword());
		String userPassword=record.getStr("password");//获取数据库已经加密的密码
		String sha256=User.encryptPassword(loginPassword, record.getStr("salt"));//获取数据库保存的盐值，加密跟数据库比对
		if(!userPassword.equals(sha256)){
			//账号或密码错误
			throw new IncorrectCredentialsException();
		}
		
		Subject subject=SecurityUtils.getSubject();
		subject.getSession().setAttribute(ConstConfig.SESSION_USER, record);
		SimpleAuthenticationInfo simpleAuthenticationInfo=new SimpleAuthenticationInfo(record.getStr("id"),loginPassword,getName());
		return simpleAuthenticationInfo;
		
	}
	
	private void addResourceOfRole(Record role, SimpleAuthorizationInfo info){
        List<Record> resources = Resource.dao.getResourcesByRoleId(role.getStr("id"));
        for(Record resource : resources ){
            //资源代码就是权限值，类似user:list:add
            info.addStringPermission(resource.getStr("code"));
        }
    }
	
	public static void main(String[] args) {
		String sha256=User.encryptPassword("123456", "123456");//获取数据库保存的盐值，加密跟数据库比对
		System.out.println(sha256);
		//3a022f9b61e72fe3fb40ff5cb0a2f6ab6277d5d0ca0a84fd14cc8356693209d7
	}

}
